<template>
    <div>
        <div class="container">
            <div class="uploadBox" v-if="step === 'upload'">
                <el-upload
                    :action="uploadFileUrl"
                    :before-upload="handleBeforeUpload"
                    :file-list="fileList"
                    :limit="limit"
                    :on-error="handleUploadError"
                    :on-exceed="handleExceed"
                    :on-success="handleUploadSuccess"
                    :on-change="handleChange"
                    :on-remove="handleDelete"
                    :on-preview="handlePreview"
                    :headers="headers"
                    :auto-upload="false"
                    class="upload-file-uploader"
                    ref="fileUpload"
                    drag
                    :multiple="multiple"
                    :accept="accept"
                >
                    <div class="content">
                        <i class="el-icon-plus"></i>
                        <div class="text">上传文件</div>
                    </div>

                    <div class="el-upload__tip" slot="tip" v-if="showTip">
                        请上传
                        <template v-if="fileSize">
                            大小不超过
                            <b style="color: #f56c6c">{{ fileSize }}MB</b>
                        </template>
                        <template v-if="fileType">
                            格式为
                            <b style="color: #f56c6c">{{
                                fileType.join("/")
                            }}</b>
                        </template>
                        的文件
                    </div>
                </el-upload>
                <div class="tips">
                    <slot name="tips"> </slot>
                </div>
                <!-- <el-button type="primary" size="default" @click="submit" -->
                <!-- >上传</el-button -->
                <!-- > -->
            </div>
            <div v-else class="uploadResult">
                <div class="container_success">
                    <div class="msg" v-if="step === 'success'">
                        <div class="icon">
                            <img
                                src="../../assets/images/check-circle@2x.png"
                                alt=""
                            />
                        </div>
                        <div class="title">导入成功</div>
                        <div>成功导入{{ uploadFilesStatus.success }}条数据</div>
                    </div>
                    <div class="msg" v-if="step === 'error'">
                        <div class="icon">
                            <img
                                src="../../assets/images/close-circle@2x.png"
                                alt=""
                            />
                        </div>
                        <div class="title">导入失败</div>
                        <div class="downloadInfo">
                            成功导入{{
                                uploadFilesStatus.success
                            }}条数据，导入失败{{
                                uploadFilesStatus.error
                            }}条，<el-button class="downloadError" type="text"
                                >下载失败文档</el-button
                            >
                        </div>
                    </div>
                    <div class="uploadFilesList">
                        <div
                            class="item"
                            v-for="item in fileList"
                            :key="item.uid"
                        >
                            <div class="icon">
                                <i class="el-icon-paperclip"></i>
                            </div>
                            <div
                                class="fileContent"
                                :class="[
                                    item.state === 'error'
                                        ? 'error'
                                        : 'success',
                                ]"
                            >
                                <div class="label">
                                    <el-tooltip
                                        effect="dark"
                                        :content="item.name"
                                        placement="top"
                                    >
                                        <div
                                            class="text"
                                            @click="_previewImages([item.url])"
                                        >
                                            {{ item.name }}
                                        </div>
                                    </el-tooltip>
                                </div>
                                <div class="status">
                                    <i
                                        v-if="item.state === 'error'"
                                        class="el-icon-close"
                                    ></i>
                                    <i
                                        v-else
                                        v-if="item.state === 'success'"
                                        class="el-icon-check"
                                    ></i>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>
<script>
import { getToken } from "@/utils/auth";
import { listByIds, delOss } from "@/api/system/oss";
import { add } from "@/api/formConfig/formDefinition";
export default {
    name: "",
    components: {},
    mixins: [],
    props: {
        // 值
        value: [String, Object, Array],
        // 数量限制
        limit: {
            type: Number,
            default: 5,
        },
        // 大小限制(MB)
        fileSize: {
            type: Number,
            default: 5,
        },
        // 文件类型, 例如['png', 'jpg', 'jpeg']
        fileType: {
            type: Array,
            default: () => ["doc", "xls", "ppt", "txt", "pdf"],
        },
        // 是否显示提示
        isShowTip: {
            type: Boolean,
            default: true,
        },
        multiple: {
            default: true,
        },
    },
    data() {
        return {
            step: "upload",
            number: 0,
            uploadList: [],
            baseUrl: process.env.VUE_APP_BASE_API,
            uploadFileUrl: process.env.VUE_APP_BASE_API + "/system/oss/upload", // 上传文件服务器地址
            headers: {
                Authorization: "Bearer " + getToken(),
            },
            fileList: [],
            fileListLength: 0,
            uploadFilesStatus: {
                success: 0,
                error: 0,
            },
        };
    },
    computed: {
        // 是否显示提示
        showTip() {
            return this.isShowTip && (this.fileType || this.fileSize);
        },
        accept() {
            let fileTypes = this.fileType?.map((item) => {
                return `.${item}`;
            });
            return fileTypes?.join(",");
        },
    },
    watch: {
        value: {
            async handler(val) {
                if (val) {
                    let temp = 1;
                    // 首先将值转为数组
                    let list;
                    if (Array.isArray(val)) {
                        list = val;
                    } else {
                        await listByIds(val).then((res) => {
                            list = res.data.map((oss) => {
                                oss = {
                                    name: oss.originalName,
                                    url: oss.url,
                                    ossId: oss.ossId,
                                };
                                return oss;
                            });
                        });
                    }
                    // 然后将数组转为对象数组
                    this.fileList = list.map((item) => {
                        item = {
                            name: item.name,
                            url: item.url,
                            ossId: item.ossId,
                            state: "success",
                        };
                        item.uid = item.uid || new Date().getTime() + temp++;
                        return item;
                    });
                } else {
                    // this.fileList = [];
                    this.initUpload();
                    return [];
                }
                this.fileListLength = this.fileList.length || 0;
            },
            deep: true,
            immediate: true,
        },
        // fileList: {
        //     deep: true,
        //     handler(val) {
        //         console.log("watch");
        //         console.log(val);
        //     },
        // },
    },
    mounted() {
        // console.log(URL);
    },
    methods: {
        initUpload() {
            this.step = "upload";
            this.fileList = [];
            this.uploadList = [];
            this.number = 0;
            this.fileListLength = 0;
            this.uploadFilesStatus = {
                success: 0,
                error: 0,
            };
            this.$nextTick(() => {
                this.$refs.fileUpload?.clearFiles();
            });
        },
        // 判断是否全部上传完毕
        checkFilesState() {
            let afterUpload =
                this.fileList.length > 0 &&
                this.fileList.reduce((prev, next) => {
                    return prev && "state" in next && next.status !== "ready";
                }, true);
            if (afterUpload) {
                this.changeStep();
            }
        },
        // 文件全部上传完毕
        changeStep() {
            this.uploadFilesStatus.success = 0;
            this.uploadFilesStatus.error = 0;
            let uploadState = this.fileList.reduce((prev, next) => {
                next?.state === "success"
                    ? (this.uploadFilesStatus.success += 1)
                    : (this.uploadFilesStatus.error += 1);
                return prev && next?.state === "success";
            }, true);
            if (uploadState) {
                this.step = "success";
            } else {
                this.step = "error";
            }
            this.$emit("afterUpload");
        },
        submit() {
            this.$refs.fileUpload.submit();
        },
        handlePreview(file) {
            let url = URL.createObjectURL(file.raw);
            this._previewImages([url]);
        },
        handleChange(file, fileList) {
            if (fileList.length > this.fileListLength) {
                // 新增
                let pass = this.lintFile(file);
                if (!pass) {
                    let index = fileList.findIndex(
                        (item) => item.uid === file.uid
                    );
                    fileList.splice(index, 1);
                }
                this.fileList = fileList;
                this.fileListLength = fileList.length;
            }
            this.checkFilesState();
        },

        handleRemove(file) {
            // console.log(file);
        },

        handleDownload(file) {
            // console.log(file);
        },
        // 上传前校检格式和大小
        handleBeforeUpload(file) {
            let pass = true;
            pass = this.lintFile(file);
            this.$modal.loading("正在上传文件，请稍候...");
            this.number++;
            return pass;
        },
        lintFile(file) {
            // 校检文件类型
            if (this.fileType) {
                const fileName = file.name.split(".");
                const fileExt = fileName[fileName.length - 1];
                const isTypeOk = this.fileType.indexOf(fileExt) >= 0;
                if (!isTypeOk) {
                    this.$modal.msgError(
                        `文件格式不正确, 请上传${this.fileType.join(
                            "/"
                        )}格式文件!`
                    );
                    return false;
                }
            }
            // 校检文件大小
            if (this.fileSize) {
                const isLt = file.size / 1024 / 1024 < this.fileSize;
                if (!isLt) {
                    this.$modal.msgError(
                        `上传文件大小不能超过 ${this.fileSize} MB!`
                    );
                    return false;
                }
            }
            return true;
        },
        // 文件个数超出
        handleExceed() {
            this.$modal.msgError(`上传文件数量不能超过 ${this.limit} 个!`);
        },
        // 上传失败
        handleUploadError(err, file, fileList) {
            let item = this.fileList.find((item) => item.uid === file.uid);
            if (item) {
                item.state = "error";
            }
            this.fileList = fileList;
            this.fileList.push(item);
            this.$modal.msgError("上传文件失败，请重试");
            this.$modal.closeLoading();
        },
        // 上传成功回调
        handleUploadSuccess(res, file, fileList) {
            this.$modal.closeLoading();
            let item = fileList.find((item) => item.uid === file.uid);
            item.name = res.data.fileName;
            item.url = res.data.url;
            item.ossId = res.data.ossId;
            if (res.code === 200) {
                this.uploadList.push({
                    name: res.data.fileName,
                    url: res.data.url,
                    ossId: res.data.ossId,
                    state: "success",
                });
                item.state = "success";
                this.$emit("uploadSuccess", res);
            } else {
                this.number--;
                this.$modal.msgError(res.msg);
                item.state = "error";
                // this.$refs.fileUpload.handleRemove(file);
            }
            this.uploadedSuccessfully();
            this.fileList = fileList;
        },
        // 删除文件
        handleDelete(file, filelist) {
            let index = this.fileList.findIndex((item) => {
                return item.uid == file.uid;
            });
            if (file.status !== "ready") {
                let item = this.fileList.find((e) => {
                    return e.uid == file.uid;
                });
                if (item?.ossId) {
                    delOss(item.ossId);
                }
                this.fileList.splice(index, 1);
                this.$emit("input", this.listToString(this.fileList));
            } else {
                this.fileList = filelist;
                this.fileListLength = this.fileList.length;
            }
        },
        // 上传结束处理
        uploadedSuccessfully() {
            if (this.number > 0 && this.uploadList.length === this.number) {
                // this.fileList = this.fileList.concat(this.uploadList);
                // this.uploadList = [];
                // this.number = 0;
                // this.$refs.fileUpload.clearFiles();
                this.$emit("input", this.listToString(this.fileList));
                this.$modal.closeLoading();
            }
        },
        // 获取文件名称
        getFileName(name) {
            // 如果是url那么取最后的名字 如果不是直接返回
            if (name.lastIndexOf("/") > -1) {
                return name.slice(name.lastIndexOf("/") + 1);
            } else {
                return name;
            }
        },
        // 对象转成指定字符串分隔
        listToString(list, separator) {
            let strs = "";
            separator = separator || ",";
            for (let i in list) {
                strs += list[i].ossId + separator;
            }
            return strs != "" ? strs.substr(0, strs.length - 1) : "";
        },
    },
};
</script>
<style lang="scss" scoped>
.container {
    // width: 300px;
    background: #fff;
    display: flex;
    justify-content: center;
    padding: 20px 0;
}
.tips {
    align-self: flex-start;
}
.uploadBox {
    width: 440px;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
}
.content {
    height: 100%;
    border: 1px dashed #d9d9d9;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    .text {
        font-size: 16px;
        color: #606266;
        margin-top: 10px;
    }
}
::v-deep .upload-file-uploader {
    display: flex;
    flex-direction: column;
    .el-upload {
        margin: 0 auto;
    }
}
::v-deep .el-upload-dragger {
    width: 300px;
    height: 180px;
}
.uploadResult {
    .msg {
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
        gap: 15px;
        .icon {
            width: 80px;
            img {
                width: 100%;
                display: block;
            }
        }
        .title {
            font-weight: bold;
            font-size: 22px;
        }
        .downloadInfo {
            font-size: 14px;
        }
    }
    .uploadFilesList {
        width: 300px;
        margin: 40px auto 0;
        .item {
            --success: #79a84b;
            --error: red;
            display: flex;
            .icon {
                width: 25px;
            }
            .fileContent {
                min-width: 0;
                flex: 1;
                border-bottom: 1px solid;
                padding-bottom: 5px;
                margin-bottom: 15px;
                display: flex;
                flex-direction: row;
                justify-content: space-between;
                align-items: center;
                .label {
                    width: 70%;
                    .text {
                        overflow: hidden;
                        white-space: nowrap;
                        text-overflow: ellipsis;
                        margin-top: 0;
                    }
                }
            }
            .success {
                border-color: var(--success);
                .status {
                    i {
                        color: var(--success);
                    }
                }
            }
            .error {
                border-color: var(--error);
                .status {
                    i {
                        color: var(--error);
                    }
                }
            }
        }
    }
}
</style>
